﻿using AnyLink.Domain.Options;
using AnyLink.Domain.ViewModels;
using AnyLink.Infrastructure.Utils;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace AnyLink.Infrastructure.Auth
{
    public static class AuthSetup
    {
        /// <summary>
        /// 添加JWT认证
        /// </summary>
        /// <param name="services"></param>
        public static void AddAuth(this IServiceCollection services)
        {
            var jwtOptions = Global.GetConfig<JwtOptions>();
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidAudience = jwtOptions.Audience,
                    ValidIssuer = jwtOptions.Issuer,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecurityKey)),
                    ClockSkew = TimeSpan.Zero
                };
                //监听JWT过期事件
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("jwtexception", "expired");
                        }
                        return Task.CompletedTask;
                    },
                    OnChallenge = context =>
                    {
                        //终止默认的返回类型和数据结果
                        context.HandleResponse();
                        //自定义数据结果
                        var payload = new ResultJsonView { Code = StatusCodes.Status401Unauthorized, Message = "很抱歉，您无权访问该接口!" }.ToJson();
                        //自定义数据类型
                        context.Response.ContentType = "application/json";
                        //自定义返回状态码
                        context.Response.StatusCode = StatusCodes.Status200OK;
                        //输出Json数据结果
                        context.Response.WriteAsync(payload);
                        return Task.FromResult(0);
                    },
                    OnMessageReceived = context =>
                    {
                        //此处可以拦截Token，用于实现登出操作
                        var token = context.HttpContext.Request.Headers["Authorization"].ToString();
                        //context.HttpContext.Request.Headers["Authorization"] = "";
                        return Task.CompletedTask;
                    }
                };
            });

        }
    }
}
